package com.xuqi.W3;


/**
 * A Runnable interface wrapper class for executing a W3Request.
 */
public class W3ThreadTask implements Runnable {

	protected W3Request				m_cRequest			= null;
	private int						m_iQueueID			= 0;
	private int						m_iRetryCountLeft   = W3Request.W3_REQ_RETRY_COUNT_0;
	private int						m_iPriority			= W3RequestExecutor.PRIO_NORMAL;
	private int						m_iErrorCode		= W3.W3_ERR_NO_ERROR;
	private DownloadEventLitener	m_cEventListener	= new DownloadEventLitener();

	public W3ThreadTask(W3Request request, int priority) {
		m_cRequest		= request;
		m_iPriority		= priority;
	}

	public int getPriority() {
		return m_iPriority;
	}

	public int getQueueID() {
		return m_iQueueID;
	}

	@Override
	public void run()
	{
		W3 w3 = getHandler();
		m_iErrorCode = W3.W3_ERR_NO_ERROR;

		if ((null == w3) || (null == m_cRequest))
		{
			m_iErrorCode = W3.W3_ERR_OTHER_ERROR;
		}

		m_iRetryCountLeft = m_cRequest.getRetryCount();
		for (; m_iRetryCountLeft >= 0; --m_iRetryCountLeft)
		{
			if (m_iRetryCountLeft == m_cRequest.getRetryCount())
			{
				if ((W3.W3_ERR_NO_ERROR == m_iErrorCode))
				{
				/*	if (!jniW3.onTaskStart(getQueueID()))
					{
						m_iErrorCode = W3.W3_ERR_REQUEST_CANCELLED;
					}*/
				}
			}
			else
			{
			/*	if ((W3.W3_ERR_NO_ERROR == m_iErrorCode) && m_cRequest.isNativeRequest())
				{
					if (!jniW3.OnTaskRestart(getQueueID()))
					{
						m_iErrorCode = W3.W3_ERR_REQUEST_CANCELLED;
					}
				}*/
			}

/*			if (W3.W3_ERR_NO_ERROR == m_iErrorCode)
			{
				w3.initW3();
				if (m_cRequest.isNativeRequest())
				{
					w3.setEventListener(m_cEventListener);
				}
				int iErrCode = w3.doW3Action(m_cRequest);
				if ((W3.W3_ERR_REQUEST_CANCELLED == iErrCode) || (W3.W3_ERR_NO_ERROR == iErrCode))
				{
					w3.clearW3();
					break;
				}
				else
				{
					w3.clearW3();
				}
			}*/
		/*	else if (m_cRequest.isNativeRequest())
			{
				m_cEventListener.onRecvFinish(m_iErrorCode, 0);
				break;
			}*/
		} // end for
	}

	protected void setQueueID(int iQueueID)
	{
		m_iQueueID = iQueueID;
	}

	/**
	 * Get HTTP protocol handler for current thread.
	 */
	private W3 getHandler()
	{
		Thread cThread = Thread.currentThread();
		if (!(cThread instanceof W3WorkerThread))
		{
			return null;
		}

		return ((W3WorkerThread) cThread).getHandler();
	}

	/**
	 * Wrapper class for dispatching events to native code.
	 */
	private class DownloadEventLitener implements W3.IW3DownloadDataListener
	{

		@Override
		public void onDiscardData()
		{
		}

		/**
		 * It's called when we have fully received a HTTP header from server.
		 * 
		 * @param iHttpStatus
		 *            [in] : the HTTP status code returned from server
		 * @param iExpectedLength
		 *            : the expected content length in bytes, or -1 if the
		 *            content length is unknown.
		 * @param strMIME
		 *            : MIME type returned from server.
		 * @param strEncoding
		 *            : content encoding returned from server.
		 * 
		 * @note Do *NOT* do time costly job inside the event handler, the
		 *       download will pause until the event handler returns.
		 */
		@Override
		public boolean onRecvHeader(int iHttpStatus, int iExpectedLength)
		{
			return false;
			//return jniW3.onRecvHeader(getQueueID(), iHttpStatus, iExpectedLength);
		}

		/**
		 * It's called when HTTP headers are received from server.
		 * 
		 * @param pszName
		 *            [IN] : name of the response header.
		 * @param pszValue
		 *            [IN] : value of the response header.
		 * 
		 * @return Return true to allow further process, return false to cancel
		 *         further operations.
		 * 
		 * @note It'll be called multiple times, once for each response header.
		 */
		@Override
		public boolean onRecvHeader(String strName, String strValue)
		{
			return false;
			//return jniW3.onRecvHeader(getQueueID(), strName, strValue);
		}

		/**
		 * It's called when any data from server is available.
		 * 
		 * @param pData
		 *            [IN] : data piece received from server.
		 * @param iDataSize
		 *            [IN] : size of the data piece in bytes.
		 * 
		 * @return Return true to allow further process, return false to cancel
		 *         further operations.
		 * 
		 * @note It's called ONLY when you request to save server response to
		 *       buffer. In such case, you MUST concatenate the contents of each
		 *       data piece delivered to build up the complete data for a URL
		 *       load.
		 * 
		 * @note You MUST copy the data delivered to this function to some where
		 *       else before return instead of keeping the data pointer.
		 */
		@Override
		public boolean onRecvData(byte[] aryData, int iDataSize)
		{
			return false;
			//return jniW3.onRecvData(getQueueID(), aryData, iDataSize);
		}

		/**
		 * It's called when the request is finished, either successful or
		 * failed.
		 * 
		 * @param iErrCode
		 *            [IN] : error code, used to identify if the request has
		 *            been finished successfully by checking if it's zero.
		 * @param pszDesc
		 *            [IN] : error message if [iErrCode] is not zero.
		 * 
		 * @note Derived classes *MUST* reply the event to [HttpConnectionProxy]
		 *       when it's received.
		 */
		@Override
		public void onRecvFinish(int iErrCode, int length)
		{
			if ((W3.W3_ERR_REQUEST_CANCELLED == iErrCode) || (W3.W3_ERR_NO_ERROR == iErrCode))
			{
				//jniW3.onTaskFinished(getQueueID(), iErrCode);
			}
			else
			{
				if (m_iRetryCountLeft == 0)
				{
					//jniW3.onTaskFinished(getQueueID(), iErrCode);
				}
			}
		}
	}
}
